package cn.example.util.toolkit;

import cn.example.project1.vo.wxpay.WXPreOrder;
import cn.example.util.ToolFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * 支付工具
 * Created by WuYubin on 2017/1/17.
 */
public class WXPayUtil {

    private final static Logger log = LoggerFactory.getLogger(WXPayUtil.class);

    private static class SingletonHolder {
        private static final WXPayUtil INSTANCE = new WXPayUtil();
    }

    private WXPayUtil() {
    }

    public static WXPayUtil getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 校验预下单对象
     *
     * @param wx 预下单对象
     * @return boolean
     */
    public boolean checkWXPreOrder(WXPreOrder wx) {
        NullUtil v = ToolFactory.getNullUtil();
        if (v.isNull(wx.getNonce_str()) || wx.getNonce_str().length() > 32) {
            log.error("预下单--->随机字符串异常：" + wx.getNonce_str());
            return false;//nonce_str
        }
        if (v.isNull(wx.getSign()) | wx.getSign().length() > 32) {
            log.error("预下单--->签名异常：" + wx.getSign());
            return false;//sign
        }
        if (v.isNull(wx.getBody()) || wx.getBody().length() > 128) {
            log.error("预下单--->商品描述异常：" + wx.getBody());
            return false;//body
        }
        if (v.isNull(wx.getOut_trade_no()) || wx.getOut_trade_no().length() > 32) {
            log.error("预下单--->商户订单号异常：" + wx.getOut_trade_no());
            return false;//out_trade_no
        }
        if (wx.getTotal_fee() <= 0) {
            log.error("预下单--->订单总金额异常：" + wx.getTotal_fee());
            return false;//total_fee
        }
        if (v.isNull(wx.getSpbill_create_ip()) || wx.getSpbill_create_ip().length() > 16) {
            log.error("预下单--->终端IP异常：" + wx.getSpbill_create_ip());
            return false;//spbill_create_ip
        }
        if ("JSAPI".equalsIgnoreCase(wx.getTrade_type()) && (v.isNull(wx.getOpenid()) || wx.getOpenid().length() > 128)) {
            log.error("预下单--->用户标识异常：" + wx.getOpenid());
            return false;//openid
        }
        if ("NATIVE".equalsIgnoreCase(wx.getTrade_type()) && (v.isNull(wx.getProduct_id()) || wx.getProduct_id().length() > 32)) {
            log.error("预下单--->产品ID异常：" + wx.getProduct_id());
            return false;//product_id
        }
        return true;
    }

    /**
     * 做字符串截取处理
     *
     * @param c   需要截取的字符串内容
     * @param len 最大长度
     * @return String
     */
    public String sub(String c, int len) {
        if (ToolFactory.getNullUtil().isNull(c) && c.length() >= len) {
            return c.substring(0, len - 3) + "...";
        }
        return c;
    }

    /**
     * 微信签名
     *
     * @param o   预下单对象
     * @param key 密钥
     * @return String
     */
    public String getSign(Object o, String key) {
        try {
            ArrayList<String> list = new ArrayList<>();
            Class cls = o.getClass();
            Field[] fields = cls.getDeclaredFields();
            for (Field result : fields) {
                result.setAccessible(true);
                if (result.get(o) != null && result.get(o) != "") {
                    if ("pkg".equals(result.getName())) {
                        list.add("package=" + result.get(o) + "&");
                    } else if (!"body".equals(result.getName()) && !"detail".equals(result.getName())) {
                        list.add(result.getName() + "=" + result.get(o) + "&");
                    } else {
                        String str = result.get(o).toString();
                        str = str.replaceAll("&lt;", "<").replaceAll("&gt;", ">");
                        list.add(result.getName() + "=" + str + "&");
                    }
                }
            }
            int var10 = list.size();
            String[] var11 = list.toArray(new String[var10]);
            Arrays.sort(var11, String.CASE_INSENSITIVE_ORDER);
            StringBuilder var12 = new StringBuilder();
            for (int var13 = 0; var13 < var10; ++var13) {
                var12.append(var11[var13]);
            }
            String var14 = var12.toString();
            var14 = var14 + "key=" + key;

            return ToolFactory.getEncryptUtil().encpUpMD5(var14);
        } catch (IllegalAccessException e) {
            log.error("微信生成签名异常：", e);
            return null;
        }
    }

    /**
     * 微信验证签名
     *
     * @param o   接收微信对象
     * @param key 密钥
     * @return String
     */
    public String checkSign(Object o, String key) {
        try {
            ArrayList<String> list = new ArrayList<>();
            Class cls = o.getClass();
            Field[] fields = cls.getDeclaredFields();
            for (Field result : fields) {
                result.setAccessible(true);
                if (result.get(o) != null && result.get(o) != "") {
                    String str = result.get(o).toString().trim();
                    if (!"sign".equalsIgnoreCase(result.getName()) && !"".equalsIgnoreCase(str)) {
                        str = str.replaceAll("&lt;", "<").replaceAll("&gt;", ">");
                        list.add(result.getName() + "=" + str + "&");
                    }
                }
            }
            int var10 = list.size();
            String[] var11 = list.toArray(new String[var10]);
            Arrays.sort(var11, String.CASE_INSENSITIVE_ORDER);
            StringBuilder var12 = new StringBuilder();

            for (int var13 = 0; var13 < var10; ++var13) {
                var12.append(var11[var13]);
            }
            String var14 = var12.toString();
            var14 = var14 + "key=" + key;
            return ToolFactory.getEncryptUtil().encpUpMD5(var14);
        } catch (IllegalAccessException e) {
            log.error("微信生成校验签名异常：", e);
            return null;
        }
    }

}
